﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RelationExpertSystem.Controllers;

namespace RelationExpertSystem
{
    public partial class EditPeopleDialog : Form
    {
        private PeopleController _controller;
        private List<Person> _people;
        private bool _pendingChanges = false;

        public List<Person> People
        {
            get { return _people; }
        }

        public EditPeopleDialog(PeopleController controller)
        {
            InitializeComponent();

            ResetSelectedPerson();
            _controller = controller;
            _people = new List<Person>();
        }

        public void LoadPeople(IEnumerable<Person> people)
        {
            ClearPeople();

            foreach (Person p in people)
                AddPerson(p);
        }

        private void ClearPeople()
        {
            _people.Clear();
            lbPeople.Items.Clear();
            cbNewFather.Items.Clear();
            cbNewMother.Items.Clear();
            cbNewSpouse.Items.Clear();
        }

        public void AddPerson(Person p)
        {
            _people.Add(p);
            lbPeople.Items.Add(p);
            cbNewFather.Items.Add(p);
            cbNewMother.Items.Add(p);
            cbNewSpouse.Items.Add(p);
        }

        public void ResetNewPerson()
        {
            txtNewName.Text = String.Empty;
            rbNewSexMale.Checked = true;
            cbNewFather.SelectedIndex = -1;
            cbNewMother.SelectedIndex = -1;
            cbNewSpouse.SelectedIndex = -1;
        }

        private void ResetSelectedPerson()
        {
            txtSelName.Text = String.Empty;
            txtSelSex.Text = String.Empty;
            txtSelMother.Text = String.Empty;
            txtSelFather.Text = String.Empty;
            txtSelSpouse.Text = String.Empty;
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            Reset();
            base.OnClosing(e);
        }

        private void HandleBtnAdd_Click(object sender, EventArgs e)
        {
            // TODO: move to controller
            // validate name
            string name = txtNewName.Text.Trim();
            if (String.IsNullOrEmpty(name))
            {
                MessageBox.Show("Invalid Name", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (_people.ContainsPerson(name))
            {
                MessageBox.Show("Duplicate names not allowed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            // validate sex -> male by default
            Sex sex = rbNewSexFemale.Checked ? Sex.Female : Sex.Male;
            Person mother = cbNewMother.SelectedItem as Person;
            Person father = cbNewFather.SelectedItem as Person;
            Person spouse = cbNewSpouse.SelectedItem as Person;

            // create person
            Person p = new Person(name, sex, father, mother, spouse);

            // add person to lb
            AddPerson(p);

            // reset New Person
            ResetNewPerson();

            _pendingChanges = true;
        }

        private void HandleLbPeople_SelectedIndexChanged(object sender, EventArgs e)
        {
            // TODO: move to controller
            Person p = lbPeople.SelectedItem as Person;
            if (Person.IsNull(p))
            {
                ResetSelectedPerson();
            }
            else
            {
                txtSelName.Text = p.Name;
                txtSelSex.Text = p.Sex.ToString();
                txtSelMother.Text = Person.IsNull(p.Mother) ? String.Empty : p.Mother.Name;
                txtSelFather.Text = Person.IsNull(p.Father) ? String.Empty : p.Father.Name;
                txtSelSpouse.Text = Person.IsNull(p.Spouse) ? String.Empty : p.Spouse.Name;
            }
        }

        private void HandleBtnSave_Click(object sender, EventArgs e)
        {
            _controller.UpdatePeople(_people);
            _controller.SavePeople();
            _pendingChanges = false;
        }

        private void HandleBtnClose_Click(object sender, EventArgs e)
        {
            if (_pendingChanges)
            {
                DialogResult result = MessageBox.Show("Do you want to save pending changes to file?",
                    "Pending Changes", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

                if (result == DialogResult.Yes)
                {
                    _controller.UpdatePeople(_people);
                    _controller.SavePeople();
                    _pendingChanges = false;
                    _controller.Close();
                }
                else if (result == DialogResult.No)
                {
                    result = MessageBox.Show("Do you want to persist changes to this session?",
                        "Pending Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

                    if (result == DialogResult.Yes)
                        _controller.UpdatePeople(_people);

                    _controller.Close();
                }
                else if (result == DialogResult.Cancel)
                {
                    return;
                }
            }

            _controller.Close();
        }

        private void HandleBtnEdit_Click(object sender, EventArgs e)
        {
            // TODO: move to controller
            Person p = lbPeople.SelectedItem as Person;
            if (Person.IsNull(p))
                return;

            List<Person> options = new List<Person>();
            for (int i = 0; i < lbPeople.SelectedIndex; i++)
            {
                Person p2 = lbPeople.Items[i] as Person;
                if (p2 != null)
                    options.Add(p2);
            }
            EditPersonDialog epd = new EditPersonDialog(p, options, _people);

            if (epd.ShowDialog() == DialogResult.OK)
            {
                _pendingChanges = epd.Changes;
                RefreshPeople();
                HandleLbPeople_SelectedIndexChanged(null, null);
            }
        }

        private void RefreshPeople()
        {
            ClearLists();
            foreach (Person p in _people)
            {
                lbPeople.Items.Add(p);
                cbNewFather.Items.Add(p);
                cbNewMother.Items.Add(p);
                cbNewSpouse.Items.Add(p);
            }
        }

        private void ClearLists()
        {
            lbPeople.Items.Clear();
            cbNewFather.Items.Clear();
            cbNewMother.Items.Clear();
            cbNewSpouse.Items.Clear();
        }

        private void Reset()
        {
            ResetNewPerson();
            ResetSelectedPerson();
            _people = new List<Person>();
            ClearLists();
        }
    }
}
